﻿//  Copyright (c) 2011 Ray Liang (http://www.dotnetage.com)
//  Licensed MIT: http://www.opensource.org/licenses/mit-license.php

using System.Collections.Generic;
using System.Linq;
using DNA.Utility;
using DNA.Mvc.Installation;
using System;

namespace DNA.Mvc.Exporting.Exporters
{
    public class WebTemplateExporter : Exporter
    {
        public override void Execute(ExportingContext context)
        {
            var web = GetMatch<Web>(context);

            if (!context.Installers.ContainsKey(Name))
            {
                var template = this.GetTemplate(web, context);

                var filename = context.Destination + (context.Destination.EndsWith("\\") ? "" : "\\") + "install.template";
                
                if (!System.IO.Directory.Exists(context.Destination))
                    System.IO.Directory.CreateDirectory(context.Destination);

                XmlSerializerUtility.SerializeToXmlFile<WebTemplate>(filename, template);

                var config = new WebTemplateConfiguration()
                {
                    Template = "install.template",
                    Replacements = new List<ReplacementConfigurationNode>()
                };

                config.Replacements.Add(new ReplacementConfigurationNode() { Match = "{website}", Value = "Web.Name" });
                config.Replacements.Add(new ReplacementConfigurationNode() { Match = "{website-title}", Value = "Web.Title" });
                config.Replacements.Add(new ReplacementConfigurationNode() { Match = "{website-desc}", Value = "Web.Description" });
                config.Replacements.Add(new ReplacementConfigurationNode() { Match = "{website-theme}", Value = "Web.Theme" });

                context.Installers.Add(Name, XmlSerializerUtility.SerializeToXml<WebTemplateConfiguration>(config).Replace("<?xml version=\"1.0\" encoding=\"utf-8\"?>",""));
            }
        }

        public override string Name
        {
            get { return "webs"; }
            set { }
        }
        
        public override string Description
        {
            get
            {
                return "Export the website settings, webpages and all widgets.";
            }
        }

        private WebTemplate GetTemplate(Web web, ExportingContext context)
        {
            var template = new WebTemplate()
            {
                Title = "{website-title}",
                Theme = "{website-theme}",
                Description = "{website-desc}",
                DefaultUrl = web.DefaultUrl,
                Language = web.DefaultLanguage,
                Copyright = web.Copyright,
                CssText = web.CssText,
                LogoImageUrl = web.LogoImageUrl,
                ShortcutIconUrl = web.ShortcutIconUrl,
                EnableUserRegistation = web.EnableUserRegistration,
                Type = WebTypes.Team,
                MasterPage = web.MasterName,
                SearchKeywords = web.SearchKeywords
            };

            if ((!string.IsNullOrEmpty(web.DefaultUrl)) && (web.DefaultUrl.IndexOf("/" + web.Name.ToLower() + "/") > -1))
                template.DefaultUrl = web.DefaultUrl.ToLower().Replace("/" + web.Name.ToLower() + "/", "/{website}/");

            var pages = web.WebPages;

            if (pages.Count() > 0)
            {
                template.WebPages = new List<WebPageTemplate>();
                var topLvPages = pages.Where(p => p.ParentID == 0).ToList();

                foreach (var page in topLvPages)
                {
                    if ((page.IsStatic) && (!page.IsShared))
                        continue;
                    template.WebPages.Add(this.GetTemplate(page, context));
                }
            }
            return template;
        }

        private WidgetTemplate GetTemplate(WidgetInstance widget, ExportingContext context)
        {
            var descriptor = widget.WidgetDescriptor;
            var tmpl = this.GetTemplate(descriptor, context);

            tmpl.Defaults = new WidgetDefaults()
            {
                Title = widget.Title,
                TitleLinkUrl = widget.TitleLinkUrl,
                IconUrl = widget.IconUrl,
                ShowBorder = widget.ShowBorder,
                ShowHeader = widget.ShowHeader,
                HeaderCssText = widget.HeaderCssText,
                CssText = widget.CssText,
                BodyCssText = widget.BodyCssText,
                Action = descriptor.Action,
                ZoneID = widget.ZoneID,
                Position = widget.Pos,
                Controller = descriptor.Controller // widget.Controller,
            };
            //tmpl.ID = widget.ID.ToString();
            tmpl.ID = descriptor.InstalledPath;
            var _preferences = widget.ReadUserPreferences();
            tmpl.UserPreferences = new List<WidgetUserPreference>();
            foreach (var key in _preferences.Keys)
            {
                tmpl.UserPreferences.Add(new WidgetUserPreference()
                {
                    Type = _preferences[key].GetType().ToString(),
                    Name = key,
                    Value = _preferences[key].ToString()
                });
            }
            return tmpl;
        }

        private WebPageTemplate GetTemplate(WebPage page, ExportingContext context)
        {
            var web = page.Web;
            var _pg = new WebPageTemplate()
            {
                Title = page.Title,
                Description = page.Description,
                Keywords=page.Keywords,
                ImageUrl=page.ImageUrl,
                IconUrl=page.IconUrl,
                LinkUrl = page.LinkUrl,
                Target = page.Target,
                Data = page.ViewData,
                Layout = page.ViewName,
                IsStatic = page.IsStatic,
                IsShared = page.IsShared,
                AllowAnonymous = page.AllowAnonymous,
                ShowInMenu = page.ShowInMenu,
                Path = page.Path
            };

            //if (web.Type != (int)WebTypes.Personal)
            _pg.Path = _pg.Path.ToLower().Replace("/" + web.Name.ToLower() + "/", "/{website}/");

            if (page.Widgets.Count > 0)
            {
                _pg.Widgets = new List<WidgetTemplate>();
                foreach (var widget in page.Widgets)
                {
                    if (!widget.IsStatic)
                        _pg.Widgets.Add(this.GetTemplate(widget, context));
                }
            }

            var children = web.WebPages.Where(p => p.ParentID == page.ID);
            if (children.Count() > 0)
            {
                _pg.Children = new List<WebPageTemplate>();
                foreach (var pc in children)
                    _pg.Children.Add(this.GetTemplate(pc, context));
            }
            return _pg;
        }

        private WidgetTemplate GetTemplate(WidgetDescriptor descriptor, ExportingContext context)
        {
            string fullPath = context.HttpContext.Server.MapPath("~/content/widgets/") + descriptor.InstalledPath + "\\config.xml";
            return XmlSerializerUtility.DeserializeFormXmlFile<WidgetTemplate>(fullPath);
        }
    }
}
